package com.longteng.diamond.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.jayway.jsonpath.InvalidPathException;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.PathNotFoundException;
import com.longteng.diamond.domain.InterfaceMock;
import com.longteng.diamond.domain.InterfaceMockData;
import com.longteng.diamond.service.MockMatchDataService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.stereotype.Component;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

import javax.servlet.http.HttpServletRequest;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Administrator
 * DATE : 2018/8/12
 * TIME : 10:24
 * PROJECT : java-lesson
 * PACKAGE : com.longteng.lesson
 *
 * @author <a href="mailto:taki@qq.com">Administrator</a>
 */
@Component
@Slf4j
public class XPathMatchImpl implements MockMatchDataService {
    /**
     * 通过xPath的方法获取mock数据
     * @param
     * @return mockData
     */
    @Override
    public String dataMatch(InterfaceMock interfaceMock, List<InterfaceMockData> interfaceMockDataList, HttpServletRequest httpRequest) {
        /**获取入参数据并且转换成document**/
        Document document=this.getDocumentObj(httpRequest);
        /**定义一个xPath解析器**/
        XPath xPath= XPathFactory.newInstance().newXPath();
        for (InterfaceMockData interfaceMockData : interfaceMockDataList) {
            String data = interfaceMockData.getMatchData();
            /**反序列化匹配数据,转换成map类型**/
            Map<String, String> map = JSON.parseObject(data, new TypeReference<HashMap<String, String>>() {
            });
            boolean isMatch = true;
            for (String key : map.keySet()) {
                String dbValue = map.get(key);
                String paramValue = null;
                try {
                    Node node=(Node) xPath.evaluate(key,document,XPathConstants.NODE);
                    if(null==node){
                        isMatch=false;
                        break;
                    }
                    paramValue=node.getNodeValue();
                } catch (XPathExpressionException e) {
                    e.printStackTrace();
                }
                if (null == paramValue || !dbValue.equalsIgnoreCase(paramValue)) {
                    isMatch = false;
                    break;
                }
            }
            if (isMatch) {
                return interfaceMockData.getMockData();
            }
        }
        return "未匹配到mock数据";
    }
    private Document getDocumentObj(HttpServletRequest httpRequest){
        InputStream inputStream=null;
        try{
            inputStream=httpRequest.getInputStream();
        }catch (Exception e){
            log.error("转换inputStream异常",e);
        }
      return   this.getDocumentObj(inputStream);
    }
    /**
     * 把入参xml数据转换成document
     * @param inputStream
     * @return Document
     */
    public Document getDocumentObj(InputStream inputStream){
        DocumentBuilder documentBuilder=null;
        Document document=null;
        try {
            documentBuilder=DocumentBuilderFactory.newInstance().newDocumentBuilder();
        } catch (ParserConfigurationException e) {
            log.error("获取文本构建实例异常",e);
        }
        try {
            document=documentBuilder.parse(inputStream);
        } catch (SAXException e) {
            log.error("转换入参异常",e);
        } catch (IOException e) {
            log.error("读取输入流异常",e);
        }
        return document;
    }
}
